package caramcraft;

import java.util.LinkedList;

import math.geom2d.Vector2D;
import jnibwapi.JNIBWAPI;
import jnibwapi.model.Unit;
import jnibwapi.types.TechType;
import jnibwapi.types.WeaponType;

public class Vulture extends SCUnit {
	private TechType spiderMine = bwapi
			.getTechType(TechType.TechTypes.Spider_Mines.getID());
	private LinkedList<Vector2D> spiderMinePositions = new LinkedList<Vector2D>();

	private Vulture otherVulture;
	private final int vultureId;
	private boolean layMine = false;
	public Vulture(Unit unit, JNIBWAPI bwapi) {
		super(unit, bwapi, bwapi
				.getWeaponType(WeaponType.WeaponTypes.Fragmentation_Grenade
						.getID()));
		vultureId = 0;
	}

	public Vulture(Unit unit, JNIBWAPI bwapi, LinkedList<SCUnit> myUnits,
			LinkedList<Unit> myBuildings, LinkedList<SCUnit> enemyUnits,
			LinkedList<Unit> enemyBuildings, int vultureId) {
		super(unit, bwapi, bwapi
				.getWeaponType(WeaponType.WeaponTypes.Fragmentation_Grenade
						.getID()), myUnits, myBuildings, enemyUnits,
				enemyBuildings);
		this.vultureId = vultureId;
	}

	public void step(long frame) {
		if (isSleep(frame))
			return;

		if (otherVulture == null)
			getOtherVulture();
		
		// get our units
		LinkedList<Tank> tanks = new LinkedList<Tank>();
		boolean isSieged = false;
		for( SCUnit u: myUnits)
		{
			if( u instanceof Tank && !u.isDead())
			{
				Tank t = (Tank)u;
				tanks.add(t);
				isSieged |= t.isSieged();
			}
		}
		// kite
		if( this.getCooldown() > 1 )
		{
			SCUnit target = this.getNearestEnemy();
			if( target != null )
			{
				if( layMine /* && getDistance(target.me) < 500 */ && this.getSpiderMines() > 0)
				{
					spiderMine(getPosition());
					sleep(frame,15);
					layMine = false;
					return;
				}
				Vector2D diff = target.getPosition().minus(this.getPosition()).opposite();
				move( getPosition().plus(diff) );
				sleep(frame,2);
			}
			return;
		}
		layMine = true;
		// if tanks are sieged
		if( isSieged )
		{
			// get nearest Tank
			Tank bestTank = null;
			Double tankDistance = Double.MAX_VALUE;
			for( SCUnit u: enemyUnits)
			{
				if( u instanceof Tank && (bestTank==null || getDistance(u.me) < tankDistance) )
				{
					bestTank = (Tank)u;
					tankDistance = getDistance(u.me);
				}
			}
			if( bestTank != null && tankDistance < this.weaponType.getMaxRange() * 1.1)
			{
				attack(bestTank.me);
				sleep(frame,2);
				return;
			}
			// attack enemy
			SCUnit enemy = this.getNearestEnemy();
			if( enemy != null )
			{
				attack(enemy.me);
				sleep(frame,2);
				return;
			}
		}
		// if we got no tanks.. just attack
		if( tanks.size() == 0 )
		{
			SCUnit enemy = this.getNearestEnemy();
			if( enemy != null )
			{
				attack(enemy.me);
				sleep(frame,2);
				return;
			}
		}
		// get middle point between tanks
		Vector2D moveTo = new Vector2D();
		for( Tank t: tanks )
			moveTo = moveTo.plus(t.getPosition());
		moveTo = new Vector2D( moveTo.x() / tanks.size(), moveTo.y() / tanks.size() );
		double radius = 150;
		if( tanks.size() == 2 )
			radius = Math.max(radius, tanks.getFirst().getPosition().minus(tanks.getLast().getPosition()).norm() * 1.5 );
		
		Tank t = (vultureId == 0 ? tanks.getFirst() : tanks.getLast());
		Vector2D dir = t.getPosition().minus(moveTo).normalize().times(radius);
		moveTo = moveTo.plus(dir);
		// seperate from other units
		moveTo = moveTo.plus(seperate(50));
		move(moveTo);
		sleep(frame,2);
	}

	public void spiderMine(Vector2D v) {
		if (getSpiderMines() > 0) {
			bwapi.useTech(me.getID(), spiderMine.getID(), (int) v.x(),
					(int) v.y());
			this.spiderMinePositions.add(v);
		}
	}

	public int getSpiderMines() {
		return me.getSpiderMineCount();
	}

	public LinkedList<Vector2D> getSpiderMinePositions() {
		return this.spiderMinePositions;
	}

	public void getOtherVulture() {
		for (SCUnit u : this.myUnits) {
			if (u instanceof Vulture && u.getID() != me.getID()) {
				this.otherVulture = (Vulture) u;
				return;
			}
		}
	}

}
